package locadora.dados;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;



import locadora.negocio.produtos.Item;
import miscelanea.Data;


public class RepositorioItem implements Repositorio{
	
	//nome do arquivo de Itens
	final String NOME_ARQUIVO = "itens.bin";
	private ObjectInputStream entrada = null;
	private ObjectOutputStream saida = null;
	//Lista de objetos a serem escritos ou de onde foram recuperados os itens.
	ArrayList<Item> arrayItem = null;
	
	/**
	 * Repositorio de Itens
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public RepositorioItem() throws FileNotFoundException, IOException, ClassNotFoundException{
		//inicia uma lista vazia
		this.arrayItem = new ArrayList<Item>();
		//busca todos os elementos constantes no arquivo
		this.recupera();
	}
	
	/**
	 * Retorna uma representação da lista de itens em formato String
	 * @return
	 */
	public String toString(){
		String resultado = "";
		for(Item item: arrayItem)
			resultado += item;
		return resultado;	
	}
	
	@Override
	public ArrayList<Object> ListarObjetos() {
		ArrayList<Object> arrayObject = new ArrayList<Object>();
		for(Item item : arrayItem){
			arrayObject.add(item);
		}
		return arrayObject;
	}

	@SuppressWarnings("unchecked")
	/**
	 * Busca todos os objetos guardados em disco
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	private void recupera() throws IOException, ClassNotFoundException{
		File file = new File(this.NOME_ARQUIVO);
		//Se o arquivo não existia e acabou de ser criado
		if(file.createNewFile()){
			//Escreve uma lista de Itens vazia no arquivo de saída e o fecha
			this.saida = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(this.NOME_ARQUIVO)));
			this.saida.writeObject(this.arrayItem);
			this.saida.close();
		}else{
			//Abre o arquivo para leitura
			FileInputStream fileInputStream = new FileInputStream(this.NOME_ARQUIVO);
			BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
			//Se houver ao menos um byte a ser lido do arquivo de entrada, assume que lá existe o objeto ArrayList de Itens
			if(bufferedInputStream.available() > 0){
				//Recupera o ArrayList e fecha o arquivo de entrada
				this.entrada = new ObjectInputStream(bufferedInputStream);
				this.arrayItem = (ArrayList<Item>) entrada.readObject();
				fileInputStream.close();
				bufferedInputStream.close();
				entrada.close();
			}
		}
	}
	
	@Override
	public void armazena() throws IOException{
		File file = new File(this.NOME_ARQUIVO);
		//Deleta o arquivo, se ele existir
		file.delete();
		this.saida = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(this.NOME_ARQUIVO)));
		//Escreve o array no arquivo de saída e fecha
		saida.writeObject(this.arrayItem);
		saida.close();
	}
	
	/**
	 * Quando este repositório é coletado pelo garbage collector ou quando a VM se encerra, armazena todos os dados em disco
	 */
	protected void finalize() throws IOException{
		this.armazena();
	}

	@Override
	public Item busca(String chave){
		for(Item item : this.arrayItem)
			if(item.getChave().equals(chave))
				return item;
		return null;
	}
	
	@Override
	public void adiciona(Object objeto) throws Exception {
		recupera();
		this.arrayItem.add((Item)objeto);
		armazena();
	}
	
	@Override
	public void remove(String chave) throws IOException{
		for(int i = 0; i < this.arrayItem.size(); i++)
			if(this.arrayItem.get(i).getChave() == chave){
				this.arrayItem.remove(i);
				break;
			}
		armazena();
	}

	public static void main(String[] args){
		
		try {
			
			RepositorioItem repositorio = new RepositorioItem();
			
			Item i1 = new Item("T1", 2, new Data("01021940"), "D1", 35, 0);
			Item i2 = new Item("T2", 2, new Data("01021940"), "D1", 35, 0);
			Item i3 = new Item("T3", 2, new Data("01021940"), "D1", 35, 0);
			Item i4 = new Item("T4", 2, new Data("01021940"), "D1", 35, 0);
			
			System.out.println("Array antes das inserções(vazio):\n\n" + repositorio);
			repositorio.adiciona(i1);
			repositorio.adiciona(i2);
			repositorio.adiciona(i3);
			repositorio.adiciona(i4);
			System.out.println("Array após as inserções:(1,2,3,4)\n\n" + repositorio);
			repositorio.armazena();
			System.out.println("Array após armazenamento(1,2,3,4):\n\n" + repositorio);
			repositorio.recupera();
			System.out.println("Array após recuperação(1,2,3,4):\n\n" + repositorio);
			repositorio.adiciona(i1);
			System.out.println("Array após inserção(1,2,3,4,1):\n\n" + repositorio);
			repositorio.armazena();
			System.out.println("Array após armazenamento(1,2,3,4,1):\n\n" + repositorio);
			repositorio.recupera();
			System.out.println("Array após recuperação(1,2,3,4,1):\n\n" + repositorio);
			
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (ClassNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
